﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Zero.DataAccess;

namespace DBCompare
{
    public partial class Form1 : Form
    {
        private List<DB> _DBList = new List<DB>();

        public Form1()
        {
            InitializeComponent();
        }

        private void cmbA_SelectedIndexChanged(object sender, EventArgs e)
        {
            btnCompare.Enabled = cmbA.SelectedIndex >= 0 && cmbB.SelectedIndex >= 0;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            var jsonFile = Path.Combine(Application.StartupPath, "DB.json");

            //初始化配置文件模板
            if (!File.Exists(jsonFile))
            {
                _DBList.Add(new DB { IP = "IP", User = "User", Password = "Password", DBList = new List<string> { "RMIS", "RMIS" } });
                _DBList.Add(new DB { IP = "IP", User = "User", Password = "Password", DBList = new List<string> { "RMIS", "RMIS" } });
                System.IO.File.WriteAllText(jsonFile, JsonConvert.SerializeObject(_DBList, Formatting.Indented), System.Text.Encoding.UTF8);
            }

            //加载配置文件
            try
            {
                var jsonText = System.IO.File.ReadAllText(jsonFile, System.Text.Encoding.UTF8);
                _DBList = JsonConvert.DeserializeObject<List<DB>>(jsonText);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            if (_DBList != null && _DBList.Count > 0)
            {
                cmbA.DataSource = _DBList.Select(item => $"{item.IP}" ).ToList();
                cmbB.DataSource = _DBList.Select(item => $"{item.IP}").ToList();
            }
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            btnCompare.Enabled = cmbA.SelectedIndex >= 0 && cmbB.SelectedIndex >= 0;
        }

        private void btnCompare_Click(object sender, EventArgs e)
        {
            var sgdmApp = Path.Combine(Application.StartupPath, "sgdm.exe");
            if (!File.Exists(sgdmApp))
            {
                MessageBox.Show("未找到对比工具！");
                return;
            }

            btnCompare.Enabled = false;

            var dbA = _DBList[cmbA.SelectedIndex];
            var jsonA = GetDBSQL(dbA);
            var jsonFileA = Path.Combine(Application.StartupPath, "jsonA.json");
            File.Delete(jsonFileA);
            File.WriteAllLines(jsonFileA, jsonA, System.Text.Encoding.UTF8);

            var dbB = _DBList[cmbB.SelectedIndex];
            var jsonB = GetDBSQL(dbB);
            var jsonFileB = Path.Combine(Application.StartupPath, "jsonB.json");
            File.Delete(jsonFileB);
            File.WriteAllLines(jsonFileB, jsonB, System.Text.Encoding.UTF8);

            System.Diagnostics.Process.Start(sgdmApp, $"\"{jsonFileA}\" \"{jsonFileB}\"");

            btnCompare.Enabled = true;
        }

        //读取数据库结构
        private List<string> GetDBSQL(DB db)
        {
            var textList = new List<string>();

            var dataBaseManage = new SQLServerDataBaseManage();
            var names = dataBaseManage.GetAllDataBaseNames(new DBManage.DataBaseManageParameter(db.IP, db.User, db.Password)).DataBaseNameList;
            var nameList = names.Intersect(db.DBList).OrderBy(item => item);
            foreach (var name in nameList)
            {
                textList.Add($"【{name}】");
                var sqlBuilder = new SqlConnectionStringBuilder();
                sqlBuilder.DataSource = db.IP;
                sqlBuilder.UserID = db.User;
                sqlBuilder.Password = db.Password;
                sqlBuilder.InitialCatalog = name;
                var connectionString = sqlBuilder.ConnectionString;
                var sqlConnection = new SqlConnection(connectionString);

                //表
                textList.Add("【表】");
                var dataTableManage = new SQLServerDataTableManage();
                var tableNames = dataTableManage.GetAllTableNames(sqlConnection).TableNameList.OrderBy(item => item);
                foreach (var tableName in tableNames)
                {
                    textList.Add(tableName);

                    var tableStructure = dataTableManage.GetTableStructure(sqlConnection, tableName).TableStructure;
                    var tableJson = JsonConvert.SerializeObject(tableStructure, Formatting.Indented);
                    textList.Add(tableJson);
                }

                //视图
                textList.Add("【视图】");
                var dataViewManage = new SQLServerDataViewManage();
                var viewNames = dataViewManage.GetAllViewNames(sqlConnection).ViewNameList.OrderBy(item => item);
                foreach (var viewName in viewNames)
                {
                    textList.Add(viewName);

                    var viewStructure = dataViewManage.GetViewStructure(sqlConnection, viewName).ViewStructure;
                    var viewJson = JsonConvert.SerializeObject(viewStructure, Formatting.Indented);
                    textList.Add(viewJson);
                }

                //函数
                textList.Add("【函数】");
                var functionManage = new SQLServerFunctionManage();
                var functionNames = functionManage.GetAllFunctionNames(sqlConnection).FunctionNameList.OrderBy(item => item);
                foreach (var functionName in functionNames)
                {
                    textList.Add(functionName);

                    var functionScript = functionManage.GetFunctionScript(sqlConnection, functionName).FunctionScript;
                    textList.Add(functionScript);
                }

                //存储过程
                textList.Add("【存储过程】");
                var procedureManage = new SQLServerProcedureManage();
                var procedureNames = procedureManage.GetAllProcedureNames(sqlConnection).ProcedureNameList.OrderBy(item => item);
                foreach (var procedureName in procedureNames)
                {
                    textList.Add(procedureName);

                    var procedureScript = procedureManage.GetProcedureScript(sqlConnection, procedureName).ProcedureScript;
                    textList.Add(procedureScript);
                }
            }

            return textList;
        }
    }
}
